package model;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.Timer;
import model.Field.Directions;
import model.Part.AfterMoveConditions;
import view.FieldPanel;
import view.GameFrame;

/**
 * De klasse Game is verantwoordelijk voor: de toetsen AFVANGEN de speler
 * VERTELLEN dat hij moet bewegen de happer STOPPEN de happer BEWEGEN het
 * speelveld OPSLAAN houden het paneel VERTELLEN dat hijzichzelf moet tekennen
 *
 * Game heeft kennis van de velden de lvls en het paneel
 *
 * Author Misja.
 */
public class Game implements KeyListener, ActionListener {

    private ArrayList<Field> level;
    private FieldPanel panel;
    public Timer timer;
    private GameFrame gameFrame;
    private Difficulties difficulty;
    
    private final int HARDDELAY = 100;
    private final int MEDIUMDELAY = 250;
    private final int EASYDELAY = 500;

    
    public enum Difficulties{
        EASY, MEDIUM, HARD
    }
    

    public Game(FieldPanel panel, GameFrame frame, LevelSpecification level) {
        
        LevelInterpreter levelInterpreter = new LevelInterpreter();      
        this.level = levelInterpreter.interpreterLevel(level);
        this.panel = panel;
        this.difficulty = level.getDifficulty();
        timer = new Timer(EASYDELAY, this);
        this.setTimerDelay();            
        this.gameFrame = frame;
        
    }

    /*
     * Tekent het speel veld
     */
    public void draw() {

        this.panel.setFields(level);
        this.panel.repaint();

    }

    /*
     * Vind een speler via zijn object type
     */
    public Part findPlayer() {

        Iterator<Field> it = this.level.iterator();
        while (it.hasNext()) {
            Field f = it.next();
            if (f.getPart() instanceof Player) {
                return f.getPart();
            }
        }
        return null;
    }

    /*
     * Vind een speler via zijn object type
     */
    public Enemy findEnemy() {

        Iterator<Field> it = this.level.iterator();
        while (it.hasNext()) {
            Field f = it.next();
            if (f.getPart() instanceof Enemy) {
                return ((Enemy) f.getPart());
            }
        }
        return null;
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
    }

    /*
     * Vangt de toets aanslagen af en beweegt de speler
     */
    @Override
    public void keyReleased(KeyEvent e) {
        if (this.timer.isRunning()) {
            switch (e.getKeyCode()) {
                case KeyEvent.VK_UP:
                    this.findPlayer().move(Directions.UP);
                    break;
                case KeyEvent.VK_DOWN:
                    this.findPlayer().move(Directions.DOWN);
                    break;
                case KeyEvent.VK_LEFT:
                    this.findPlayer().move(Directions.LEFT);
                    break;
                case KeyEvent.VK_RIGHT:
                    this.findPlayer().move(Directions.RIGHT);
                    break;
            }
            draw();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        AfterMoveConditions actionPerformed = findEnemy().move(getDifficulty());
        draw();
        switch (actionPerformed) {
            case NOTMOVED:
                timer.stop();
                this.gameFrame.messageDialog("U heeft gewonnen");
                this.gameFrame.dispose();
                break;
            case LASTMOVE:
                timer.stop();
                this.gameFrame.messageDialog("U heeft verloren");
                this.gameFrame.dispose();
                break;
            case MOVED:
                break;
        }
    }
    
    
    /**
     * @return the difficulty
     */
    public Difficulties getDifficulty() {
        return difficulty;
    }

    /**
     * @param difficulty the difficulty to set
     */
    public void setDifficulty(Difficulties difficulty) {
        this.difficulty = difficulty;
        this.setTimerDelay();
    }
    
    public void start(){
        this.timer.start();
    }
    
    public void stop(){
        this.timer.stop();
    }
    
    public void pauze(){
        this.timer.stop();
    }
    
    private void setTimerDelay(){
        if(this.difficulty == Difficulties.HARD){
           timer.setDelay(HARDDELAY);
        } else if(this.difficulty == Difficulties.MEDIUM){
           timer.setDelay(MEDIUMDELAY);
        } else {
            timer.setDelay(EASYDELAY);
        }
    }
}
